/*
 * wtr-packet.h
 *
 *  Created on: Jul 30, 2012
 *      Author: adroaldo
 */

#ifndef WTR_PACKET_H_

#define WTR_PACKET_H_

#include <packet.h>
#include"constants.h"

#define FC_LEN 1

/*Defining packets format*/
#define DELETED_PCKT                  0x00                /*binary representation 00000000*/
#define NORMAL_TOKEN                  0x01                /*binary representation 00000001*/
#define ELECTION_TOKEN                0x02		          /*binary representation 00000010*/
#define ELECTED_TOKEN                 0x03                /*binary representation 00000011*/
#define SOLICIT_SUCCESSOR             0x04                /*binary representation 00000100*/
#define SET_PREDECESSOR               0x05                /*binary representation 00000101*/
#define SET_SUCCESSOR                 0x06 		          /*binary representation 00000110*/
#define DATA_PCKT 			          0x07                /*binary representation 00000111*/
#define ACK_DATA_PCKT                 0x08                /*binary representation 00001000*/
#define VARAL_TOKEN			          0x09                /*binary representation 00001001*/
#define VARAL_ELECTION_TOKEN          0x0A	    	      /*binary representation 00001010*/
#define VARAL_ELECTED_TOKEN           0x0B			      /*binary representation 00001011*/
#define VARAL_SOLICIT_SUCCESSOR       0x0C			      /*binary representation 00001100*/
#define VARAL_SET_PREDECESSOR         0x0D			      /*binary representation 00001101*/
#define VARAL_SET_SUCCESSOR           0x0E				  /*binary representation 00001110*/
#define VARAL_DATA_TOKEN              0x0F				  /*binary representation 00001111*/
#define VARAL_ACK_DATA                0x010               /*binary representation 00010000*/
#define SELF_ADVERTISING              0x011               /*binary representation 00010001*/

/*Acesso direto aos headers de pacotes*/
#define HDR_WTRP_PACKET(p) ((hdr_wtrp_packet *)hdr_wtrp_packet::access(p))
#define HDR_DEL(p) ((hdr_del *)hdr_wtrp_packet::access(p))
#define HDR_TOKEN(p) ((hdr_token *)hdr_wtrp_packet::access(p))
#define HDR_ELECTION(p) ((hdr_election *)hdr_wtrp_packet::access(p))
#define HDR_ELECTED(p) ((hdr_elected *)hdr_wtrp_packet::access(p))
#define HDR_SSUCC(p) ((hdr_ssucc *)hdr_wtrp_packet::access(p))
#define HDR_SPRED(p) ((hdr_spred *)hdr_wtrp_packet::access(p))
#define HDR_SESUC(p) ((hdr_sesuc *)hdr_wtrp_packet::access(p))
#define HDR_VTOKEN(p) ((hdr_vtoken *)hdr_wtrp_packet::access(p))
#define HDR_VELECTION(p) ((hdr_velection *)hdr_wtrp_packet::access(p))
#define HDR_VELECTED(p) ((hdr_velected *)hdr_wtrp_packet::access(p))
#define HDR_VSSUCC(p) ((hdr_vssucc *)hdr_wtrp_packet::access(p))
#define HDR_VSPRED(p) ((hdr_vspred *)hdr_wtrp_packet::access(p))
#define HDR_VSESUC(p) ((hdr_vsesuc *)hdr_wtrp_packet::access(p))
#define HDR_ADVERTISING(p) ((hdr_advertising *)hdr_wtrp_packet::access(p))

/* Pacote default*/
struct hdr_wtrp_packet {

	u_int8_t FC;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_wtrp_packet);
		assert(size_var >= 0);
		return size_var;
	}
	// acesso ao header
	static int offset_;
	inline static int& offset() {
		return offset_;
	}
	inline static hdr_wtrp_packet* access(const Packet *p) {
		return (hdr_wtrp_packet*) p->access(offset_);
	}
};

struct hdr_token {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	u_int8_t nOn;
	u_int32_t seq;
	u_int32_t gen_seq;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_token);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_election {

	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA; /*Broadcast address*/
	nsaddr_t SA;
	u_int32_t max_power;
	u_int32_t n_Ch;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_election);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_elected {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	nsaddr_t ELECTED;
	char data;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_elected);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_spred {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	u_int8_t nOn;
	u_int32_t seq;
	u_int32_t gen_seq;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_spred);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_sesuc {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	nsaddr_t NEW_SUCC;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_sesuc);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_vtoken {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	u_int8_t nOn;
	u_int32_t seq;
	u_int32_t gen_seq;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_vtoken);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_velection {

	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA; /*Broadcast address*/
	nsaddr_t SA;
	u_int32_t max_power;
	u_int32_t n_Ch;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_velection);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_velected {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	nsaddr_t ELECTED;
	char data;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_velected);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_vspred {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	u_int8_t nOn;
	u_int32_t seq;
	u_int32_t gen_seq;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_vspred);
		assert(size_var >= 0);
		return size_var;
	}
};

struct hdr_vsesuc {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	nsaddr_t NEW_SUCC;
	static int offset_;

	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_vsesuc);
		assert(size_var >= 0);
		return size_var;
	}
};

/*Self advertisement*/
struct hdr_advertising {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA; /*Broadcast address*/
	nsaddr_t SA;
	static int offset_;

	/*Teste*/
	double send_time;
	int ret;
	inline int size() {
		int size_var = 0;
		size_var = sizeof (struct hdr_advertising);
		assert(size_var >= 0);
		return size_var;
	}
};

struct s_successor {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
	u_int8_t nOn;
	nsaddr_t NEW_SUC; /*address of prospective successor*/

};

typedef struct {

} data;

struct ack_pkt {
	u_int8_t FC;
	nsaddr_t RA;
	nsaddr_t DA;
	nsaddr_t SA;
};

union hdr_all_packets {
	hdr_wtrp_packet p_wtrp;
	hdr_advertising p_advert;
	hdr_elected p_elected;
	hdr_election p_election;
	hdr_sesuc p_sesuc;
	hdr_spred p_spred;
	hdr_token p_token;
	hdr_velected p_velected;
	hdr_velection p_velection;
	hdr_vsesuc p_vsesuc;
	hdr_vspred p_vspred;
	hdr_vtoken p_vtoken;
};
#endif /* WTR_PACKET_H_ */
